#!/usr/bin/python3
# ******************************************************************************
# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
# licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#     http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# ******************************************************************************/
"""
Description: check method's entrance for custom commands
Class:CheckCommand
"""

from javcra.api.jenkins_api import JenkinsJob
from javcra.application.checkpart.checktest import CheckTest
from javcra.application.modifypart.modifyentrance import IssueOperation
from javcra.application.serialize.serialize import CheckSchema
from javcra.cli.base import BaseCommand

from javcra.cli.commands import parameter_permission_validate
from javcra.common import constant
from javcra.common.constant import (
    GITEE_TOKEN,
    GITEE_REPO,
    PAEAL_NUM,
    REALSE_TOOLS_BUCKET_NAME,
    REALSE_TOOLS_SERVER,
)

from javcra.api.obscloud import ObsCloud
from javcra.libs.log import logger


class CheckCommand(BaseCommand):
    """
    Description: start the check part
    Attributes:
        sub_parse: Subcommand parameters
        params: Command line parameters
    """

    def __init__(self):
        """
        Description: Instance initialization
        """
        super(CheckCommand, self).__init__()
        self.sub_parse = BaseCommand.subparsers.add_parser(
            "check", help="release assistant of check part"
        )
        self.add_issueid_arg()
        self.add_giteeid_arg()
        self.sub_parse.add_argument(
            "--type",
            help="the type of check part, \
                including requires, issue status and test result",
            action="store",
            nargs=None,
            required=True,
            choices=["status", "requires", "test"],
        )

    def jenkins_server(self, params, PAEAL_NUM):

        jenkins_server = JenkinsJob(
            constant.JENKINS_BASE_URL,
            constant.JENKINS_USER,
            constant.JEKINS_PASS,
            PAEAL_NUM,
            self.issue(params).get_update_issue_branch(),
            self.issue(params).date,
        )
        return jenkins_server

    def check(self, params):
        check = CheckTest(GITEE_REPO, GITEE_TOKEN, params.releaseIssueID)
        return check

    def issue(self, params):
        issue = IssueOperation(GITEE_REPO, GITEE_TOKEN, params.releaseIssueID)
        return issue

    def status_operation(self, params):
        check_res = self.issue(params).check_issue_state()
        return check_res

    def requires_operation(self, params):

        #  华为云删除install check 归档
        # ak sk  获取方式
        cloud_server = ObsCloud(
            constant.AK, constant.SK, REALSE_TOOLS_SERVER, REALSE_TOOLS_BUCKET_NAME
        )
        res = cloud_server.delete_dir("install_build_log")
        print(res)
        issue = self.issue(params)
        jenkins_server = self.jenkins_server(params, PAEAL_NUM)
        check_res = issue.operate_release_issue(
            operation="add", operate_block="requires"
        )
        install_jobs_params = {
            "ScanOSSAPIURL": constant.JENKINS_API_URL,
            "ScanOSSResultRepo": constant.JENKINS_SERVER_REPO,
            "ARCH": "x86_64",
            "EPOL": "False",
            "UPDATE_TIME": "20210630",
            "BRANCH": issue.get_update_issue_branch(),
            "PKGLIST": ",".join(issue.get_update_list()),
        }
        # 触发obs_job所需参数
        obs_job_params = {
            "ScanOSSAPIURL": constant.JENKINS_API_URL,
            "ScanOSSResultRepo": constant.JENKINS_SERVER_REPO,
            "action": "create",
            "obs_project": "openEuler:20.09",
            "update_dir": "update_20210630",
            "package_family": "standard",
        }
        # 验证依赖是否通过，并将缺失的依赖回写到issue描述中

        if not check_res:
            print("[ERROR] failed to get requires.")
            return
        print("[INFO] successfully get requires.")

        # 添加repo内容到release issue中
        add_res = issue.add_repo_in_table()
        if not add_res:
            print("[ERROR] failed to add repo in release issue.")
            return
        print("[INFO] failed to add repo in release issue.")

        # 将rpm包传到服务器, 并将Jenkins job 结果评论在release issue上
        obs_pkgs = issue.get_update_list()
        obs_job_params["pkgnamelist"] = ",".join(obs_pkgs)
        job_res = self.jenkins_server(params, PAEAL_NUM).get_specific_job_status(
            obs_job_params, constant.OBS_RELEASE_JOB
        )
        print("上传服务器结果:", job_res)

        comment_res = issue.create_jenkins_comment(job_res)
        if not comment_res:
            print("[ERROR] failed to create jenkins comment.")
        else:
            print("[INFO] successfully create jenkins comment.")

        # 进行自编译验证
        install_build_pkgs = issue.get_update_list()
        self.jenkins_server(params, PAEAL_NUM).create_selfbuild_jenkins_jobs(
            install_build_pkgs
        )
        build_status_res = self.jenkins_server(
            params, PAEAL_NUM
        ).get_selfbuild_job_status()

        build_comment_res = issue.create_jenkins_comment(build_status_res)
        if not build_comment_res:
            print("[ERROR] failed to create install build jenkins comment.")
            return
        print("[INFO] successfully create install build jenkins comment.")

        # 进行安装验证
        install_status_res = jenkins_server.get_specific_job_status(
            install_jobs_params, constant.JENKINS_INSTALL_JOB
        )
        install_comment_res = issue.create_jenkins_comment(install_status_res)
        if not install_comment_res:
            print("[ERROR] failed to create install build jenkins comment.")
            return
        else:
            print("[INFO] successfully create install build jenkins comment.")

        # 开始解析安装自编译的结果
        branch = issue.get_update_issue_branch()
        if not branch:
            logger.error("[ERROR] Failed to obtain branch information. Procedure")
            return

        parsed_install_build_res = cloud_server.parse_install_build_content(branch)

        # 自编译安装失败的，创建issue，并回写issue描述
        def write_back(install_or_build, pkgs):
            """

            Args:
                install_or_build:
                pkgs:

            Returns:

            """
            install_or_build_dict = {"build_list": "build", "install_list": "install"}
            for pkg in pkgs:
                issue_id = issue.create_install_build_issue(
                    install_or_build_dict.get(install_or_build), pkg
                )
                if issue_id:
                    created_res = issue.operate_release_issue(
                        operation="add",
                        operate_block="install_build",
                        issues=[issue_id],
                    )
                    print(created_res)

        for install_or_build, pkgs in parsed_install_build_res.items():
            write_back(install_or_build, pkgs)

    def test_operation(self, params):
        check_res = self.check(params).people_review()
        if not check_res:
            print("[ERROR] failed to check.")
            return False
        print("[INFO] check successfully.")
        return

    def do_command(self, params):
        """
        Description: Executing command
        Args:
            params: Command line parameters
        Returns:

        Raises:

        """
        comment_dict = {
            "status": "/check-status",
            "requires": "/get-requires",
            "test": "/test-ok",
        }
        comment = comment_dict.get(params.type)
        if not comment:
            print("not allowed operation, please check.")
            return
        param_dict = {
            "issueid": params.releaseIssueID,
            "giteeid": params.giteeid,
            "type": params.type,
        }
        validate_result = parameter_permission_validate(
            CheckSchema, param_dict, comment
        )
        if not validate_result:
            return

        res = getattr(self, "{}_operation".format(params.type))(params)
        print(res)
